#ifndef _INETADDR_HPP_

#define _INETADDR_HPP_

#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <strings.h>
//#include <>

namespace InetAddrModule
{
#define INET_PTR(Inet) ((const struct sockaddr *)(&Inet))

// 将网络序列格式化。
class InetAddr
{
    public:
        // 绑定发送时要将本地序列转换为网络序列操作。
        // 收到消息时网络序列本地序列操作。
        // 服务端是网络序列。客户端是本地序列。
        // 网络序列转主机序列(好作为账号打印出来)
        InetAddr(struct sockaddr_in& addr)
        {
            SetAddr(addr);
            // // 4字节网络风格的IP -> 点分十进制的字符串风格的IP
            // _ip = inet_ntoa(_addr.sin_addr);
            // _port = ntohs(_addr.sin_port);
        }
        // 主机转网络(参数_port和_ip都应该是本地的)
        InetAddr(const std::string& ip,int port)
            :_port(port)
            ,_ip(ip)
        {
            bzero((void*)&_addr,sizeof(_addr));
            _addr.sin_family = AF_INET;
            inet_pton(AF_INET, _ip.c_str(), &_addr.sin_addr);
            _addr.sin_port = htons(_port);
            // local.sin_addr.s_addr = inet_addr(_ip.c_str()); // TODO
            // _port= htons(port);
            // char buffer[64];
            // inet_pton(AF_INET,_ip.c_str(),&_addr.sin_addr);
        }
        InetAddr(uint16_t port)
            :_port(port)
            ,_ip()
        {
            bzero((void*)&_addr,sizeof(_addr));
            _addr.sin_family = AF_INET;
            _addr.sin_port = htons(_port);
            _addr.sin_addr.s_addr = INADDR_ANY;
        }
        ~InetAddr()
        {
            ;
        }
        // 网络转主机好打印。
        void SetAddr(struct sockaddr_in& addr)
        {
            _addr = addr;
            _port = ntohs(_addr.sin_port);
            char buffer[64];
            inet_ntop(AF_INET,&_addr.sin_addr,buffer,sizeof(_addr));
            _ip = buffer;
        }
        const std::string& Ip()
        {
            return _ip;
        }
        uint16_t Port()
        {
            return _port;
        }
        const struct sockaddr_in &Addr()
        {
            return _addr;
        }
        std::string Name()
        {
            std::string ret;

            ret += (_ip + ":" + std::to_string(_port));

            return ret;
        }
        bool operator == (InetAddrModule::InetAddr&& self)
        {
            return (self.Ip() == _ip) && (self.Port() == _port);
        }
        const struct sockaddr_in &NetAddr()
        {
            return _addr;
        }
        socklen_t NetAddrLen()
        {
            return sizeof(_addr);
        }
        const struct sockaddr* NetAddrPtr()
        {
            return INET_PTR(_addr);
        }
    private:
        // _addr存储的是网络。
        // _ip和_port存储的是本地。
        struct sockaddr_in _addr;
        std::string _ip;
        uint16_t _port;
};
}

#endif